using System;

using AGG.UI;
using AGG.Image;
using AGG.VertexSource;
using AGG.RasterizerScanline;

namespace AGG
{
    public class trans_curve1_application : MatchParentBoundsWidget
    {
        PolygonEditWidget m_poly;
        SliderWidget m_num_points;
        CheckBoxWidget m_close;
        CheckBoxWidget m_preserve_x_scale;
        CheckBoxWidget m_fixed_len;
        CheckBoxWidget m_animate;
        double[]                       m_dx = new double[6];
        double[]                       m_dy = new double[6];

        GuiHalSurface guiSurface;

        public trans_curve1_application(GuiHalSurface guiSurface)
        {
            this.guiSurface = guiSurface;

            m_poly = new PolygonEditWidget(6, 5);
            on_init();
            m_poly.Changed += NeedsRedraw;
            AddChild(m_poly);

            m_num_points = new AGG.UI.SliderWidget(5, 5, 340, 12);

            m_num_points.ValueChanged += new SliderWidget.ValueChangedEventHandler(NeedsRedraw);

            AddChild(m_num_points);

            m_num_points.label("Number of intermediate Points = {0:F3}");
            m_num_points.range(10, 400);
            m_num_points.value(200);

            m_close = new CheckBoxWidget(350, 5.0, "Close");
            m_close.CheckedStateChanged += NeedsRedraw;
            AddChild(m_close);

            m_preserve_x_scale = new CheckBoxWidget(460, 5, "Preserve X scale");
            m_preserve_x_scale.CheckedStateChanged += NeedsRedraw;
            AddChild(m_preserve_x_scale);

            m_fixed_len = new CheckBoxWidget(350, 25, "Fixed Length");
            m_fixed_len.CheckedStateChanged += NeedsRedraw;
            AddChild(m_fixed_len);

            m_animate = new CheckBoxWidget(460, 25, "Animate");
            m_animate.CheckedStateChanged += new CheckBoxWidget.CheckedStateChangedEventHandler(m_animate_CheckedStateChanged);
            AddChild(m_animate);
        }

        void on_init()
        {
            m_poly.SetXN(0, 50);
            m_poly.SetYN(0, 50);
            m_poly.SetXN(1, 150 + 20);
            m_poly.SetYN(1, 150 - 20);
            m_poly.SetXN(2, 250 - 20);
            m_poly.SetYN(2, 250 + 20);
            m_poly.SetXN(3, 350 + 20);
            m_poly.SetYN(3, 350 - 20);
            m_poly.SetXN(4, 450 - 20);
            m_poly.SetYN(4, 450 + 20);
            m_poly.SetXN(5, 550);
            m_poly.SetYN(5, 550);
        }

        Random rand = new Random();

        void m_animate_CheckedStateChanged(object sender, EventArgs e)
        {
            if (m_animate.Checked)
            {
                on_init();
                int i;
                for (i = 0; i < 6; i++)
                {
                    m_dx[i] = ((rand.Next() % 1000) - 500) * 0.01;
                    m_dy[i] = ((rand.Next() % 1000) - 500) * 0.01;
                }

                Invalidate();

                guiSurface.Idle += new GuiHalSurface.IdleEventHandler(guiSurface_Idle);
            }
            else
            {
                guiSurface.Idle -= new GuiHalSurface.IdleEventHandler(guiSurface_Idle);
            }
        }

        void NeedsRedraw(object sender, EventArgs e)
        {
            Invalidate();
        }


        public override void OnDraw(Graphics2D graphics2D)
        {
            graphics2D.Clear(RGBA_Bytes.White);

            base.OnDraw(graphics2D);
        }


        void move_point(ref double x, ref double y, ref double dx, ref double dy)
        {
            if (x < 0.0) { x = 0.0; dx = -dx; }
            if (x > this.Width) { x = this.Width; dx = -dx; }
            if (y < 0.0) { y = 0.0; dy = -dy; }
            if (y > this.Height) { y = this.Height; dy = -dy; }
            x += dx;
            y += dy;
        }

        void guiSurface_Idle(object sender)
        {
            int i;
            for (i = 0; i < 6; i++)
            {
                double x = m_poly.GetXN(i);
                double y = m_poly.GetYN(i);
                move_point(ref x, ref y, ref m_dx[i], ref m_dy[i]);
                m_poly.SetXN(i, x);
                m_poly.SetYN(i, y);
            }
            Invalidate();
        }

    public static void StartDemo()
        {
            GuiHalFactory.SetGuiBackend(GuiHalFactory.KnownGuiFactoriesIndexes.WindowsFormsBitmap);
            GuiHalSurface primaryWindow = GuiHalFactory.CreatePrimarySurface(600, 600, GuiHalSurface.CreateFlags.Resizable, GuiHalSurface.PixelFormat.PixelFormatBgra32);

            primaryWindow.Caption = "AGG Example. Non-linear \"Along-A-Curve\" Transformer";

            primaryWindow.AddChild(new trans_curve1_application(primaryWindow));
            primaryWindow.Run();
        }

        [STAThread]
        public static void Main(string[] args)
        {
        	StartDemo();
        }
    }
}
